package com.main;

import javax.swing.*;
import java.util.Arrays;

/**
 * @Author: Painter
 * @project_name: 五子棋
 * @time: 2022/7/29 21:36
 */


public class AI {
    public static int [][] lst;  // 存放落下的所有棋子，数组

    public static void luozi(int type, GamePanel panel) {
        lst = panel.allChessList;  // 将所有棋子数组赋值给lst
        int[] lst2 = getPointer();  // 调用方法获取AI下步落子的坐标
        int x = lst2[0];  // AI落子x坐标
        int y = lst2[1];  // AIy落子坐标
        if (panel.allChessList[x][y] == 0 && panel.computerluozi) {  // 如果当前坐标在所有棋子数组中为0（没有棋子）和电脑落子布尔值为true（表示该电脑下棋）
            Chess chess = new Chess(x * 40 + 2, y * 40 + 2, type);  // 创建一个新棋子。白棋
            panel.chessList.add(chess);  // 向已经落下的棋子数组集合中添加棋子
            panel.allChessList[x][y] = 1;  // 修改所有落棋数字对应的坐标的值为1，表示在此坐标下子
            System.out.println("电脑落子");
            System.out.println("("+x+","+y+")");
            chess.last = true;  // 表示但钱这个棋子是最后一个棋子（方便在落子上做标记）
            if (panel.JudgingWin(1, x, y) == 1) {  // 判断白棋有没有五子连珠的情况，如果有，白棋胜利
                GamePanel.gameFlag = "end";
                System.out.println("电脑胜利");
                JOptionPane.showMessageDialog(null,"很遗憾！电脑胜利了！！！");  // 弹出提示信息对话框
            }else{  // 如果白棋没有五子连珠
                panel.playerluozi = true;  // 修改玩家落子的布尔值为true（让玩家落子）
            }
        }

    }

    public static int[] getPointer(){  // 获取AI落子坐标
        int x ;  // 定义AI落子x坐标
        int y ;  // 定义AI落子y坐标
        int score = 0;  // 定义评分，默认为0
        int [] tmp1 = new int[3];  // 定义黑棋判断返回数组0：评分，1：x坐标，2：y坐标
        int [] tmp2 = new int[3];  // 定义白棋判断返回数组0：评分，1：x坐标，2：y坐标

        // 判断计算玩家棋子
        for (int i = 0; i < 15; i++) {
            for (int j = 0; j < 15; j++) {
                if (lst[i][j] == 2){  // 玩家棋子，黑棋
                    int[] tmp = catchChessModel(i,j);  // 调用方法获取   索引0：记录此位置的棋子可产生的最大威胁值或优势值，索引1：对应下棋横坐标，索引2：对应下棋横坐标
                    if (tmp[0]>score){  // 如果评分大于当前评分
                        score = tmp[0];  // 更新评分
                        tmp1 = tmp;  // 更新返回数组
                    }
                }
                if (lst[i][j] == 1){  // Ai棋子，白棋
                    int[] tmp = catchChessModelb(i,j);  // 调用方法获取评分和破解坐标
                    if (tmp[0]>score){
                        score = tmp[0];
                        tmp2 = tmp;
                    }
                }
            }
        }
        x = (tmp1[0]>tmp2[0])?tmp1[1] : tmp2[1];  // 如果tmp1的评分大于tmp2的评分，就将tmp1的x坐标赋值给x，否则将tmp2的x坐标赋值给x
        y = (tmp1[0]>tmp2[0])?tmp1[2] : tmp2[2];

//        System.out.println("tmp1"+Arrays.toString(tmp1));
//        System.out.println("tmp2"+Arrays.toString(tmp2));
//        System.out.println("x,y:"+x+y);

        return new int[]{x,y};  // 返回一个AI落子坐标数组
    }
    public static int[] catchChessModel(int x, int y) {

        int[] position = new int[3];  // 创建一个长度为3 的数组存储当前棋子的评分坐标，0评分，1x坐标，2y坐标

        // 以参数点为中心点，保存四个方向的棋型，方向分别为 — | \ /
        int[][] model = new int[4][11];          // 创建以被捕捉棋子为中心的四个方向形成的棋型
        for (int[] tmp : model) {
            Arrays.fill(tmp, 8);  // 将数组的每个元素设置为8
        }
        // 把参数点放入每行的中心部位
        model[0][5] = model[1][5] = model[2][5] = model[3][5] = lst[x][y];

        for (int i = 0; i < 5; i++) {
            // 水平方向
            // 水平方向棋型
            if (x - i >= 0) {// 如果没有走出边界
                model[0][5 - i] = lst[x - i][y];// 将左侧棋子记录到水平棋型当中
            }
            if (x + i <= 14) {// 如果没有走出边界
                model[0][5 + i] = lst[x + i][y];// 将右侧棋子记录到水平棋型当中
            }

            // 垂直方向棋型
            if (y - i >= 0) {// 如果没有走出边界
                model[1][5 - i] = lst[x][y - i];// 将上方棋子记录到垂直棋型当中
            }
            if (y + i <= 14) {// 如果没有走出边界
                model[1][5 + i] = lst[x][y + i];// 将下方棋子记录到垂直棋型当中
            }

            // 反斜杠方向棋型
            if (x - i >= 0 && y + i <= 14) {// 如果没有走出边界
                model[2][5 - i] = lst[x - i][y + i];// 将左下方棋子记录到反斜棋型当中
            }
            if (x + i <= 14 && y - i >= 0) {// 如果没有走出边界
                model[2][5 + i] = lst[x + i][y - i];// 将右上方棋子记录到反斜棋型当中
            }

            // 正斜杠方向棋型
            if (x - i >= 0 && y - i >= 0) {// 如果没有走出边界
                model[3][5 - i] = lst[x - i][y - i];// 将左上方棋子记录到正斜棋型当中
            }
            if (x + i <= 14 && y + i <= 14) {// 如果没有走出边界
                model[3][5 + i] = lst[x + i][y + i];// 将右下方棋子记录到正斜棋型当中
            }
        }

        int score = 0;// 记录最大评分（威胁值）
        int direction = -1;// 记录最大评分的方向（model数组一维下标）
        int index = 0;// 记录坐标偏移量(judgeModle()方法给予的破解位置)
        for (int i = 0; i < model.length; i++) {// 遍历棋型数组
            int getResult[] = judgeModle(model[i]);// 针对此方向棋型，给予破解方案
            if (score < getResult[1]) {// 如果出现比当前最大威胁值还要大的威胁
                score = getResult[1];// 更新最大分（威胁值）
                // 被捕捉的棋子在模型中的索引为5，getResult[0]为破解方案中的下棋索引位置
                // getResult[0] - 5 = 破解位置距离被捕捉的棋子的索引位置
                index = getResult[0] - 5;//
                direction = i;// 记录此棋型的方向
            }
        }
        switch (direction) {// 判断最大威胁值所在的方向
            case 0:// 如果是水平方向
                x += index;// 下棋的位置是原位置向右（或向左）偏移index的值
                break;
            case 1:// 如果是垂直方向
                y += index;// 下棋的位置是原位置向下（或向上）偏移index的值
                break;
            case 2:// 如果是反斜方向
                x += index;// 下棋的位置是原位置向右（或向左）偏移index的值
                y -= index;// 下棋的位置是原位置向上（或向下）偏移index的值
                break;
            case 3:// 如果是正斜方向
                x += index;// 下棋的位置是原位置向右（或向左）偏移index的值
                y += index;// 下棋的位置是原位置向下（或向上）偏移index的值
                break;
        }
        position[0] = score;// 记录此棋子的最大评分（威胁值）
        position[1] = x;// 记录对应下棋横坐标
        position[2] = y;// 记录对应下棋纵坐标

        return position;// 返回结果数组
    }
    public static int[] judgeModle(int model[]) {
        int piont[] = new int[2];// 初始化返回结果数组
        int score = 0;// 记录最大评分
        StringBuffer sb = new StringBuffer();// 准备将棋型数组保存为字符串的StringBuffer
        for (int num : model) {// 遍历数组，将数组变成字符串
            if (num == 1) {// 如果是白子
                num = 4;// 改为其他数字，以免负号会占字符
            }
            sb.append(num);// 字符串添加此数字
        }

        Object library[][] = getModelLibrary();// 获取棋型库中所有棋型及其解决方案
        for (int i = 0; i < library.length; i++) {// 遍历棋型库
            String chessModel = (String) library[i][0];// 获取库中棋型
            int modelIndex = -1;// 临时变量，用于保存某棋型在字符串中出现的索引位置
            if ((modelIndex = sb.indexOf(chessModel)) != -1) {// 如果存在此棋型，则将棋型出现的位置付给modelIndex
                int scoreInLib = (int) library[i][1];// 获取棋型评分
                int stepIndex = (int) library[i][2];// 获取对应的下棋位置
                if (score < scoreInLib) {// 如果出现更高的评分
                    score = scoreInLib;// 更新最大分
                    // 记录应该(在这一行中)下棋的实际索引位置。
                    // 棋型在字符串中的索引位置 + 棋型给出的解决位置 = 字符串中的解决位置
                    piont[0] = modelIndex + stepIndex;
                    piont[1] = score;// 记录最大分数
                }
            }
        }
        return piont;// 返回结果数组
    }
    private static Object[][] getModelLibrary() {
        // 棋型库数组，第一列保存棋型字符串，第二列保存棋型估值,第三列保存针对此棋型的下法
        Object[][] library = new Object[28][3];
        // 一行可能出现的棋型，1表示棋子，0表示空位置
        String livefour = "022220";// 活四棋型
        String deadfour1a = "0222";// 死四棋型1
        String deadfour1b = "22220";
        String deadfour2a = "22202";// 死四棋型2
        String deadfour2b = "20222";
        String deadfour3 = "22022";// 死四棋型3
        String livethree = "02220";// 活三棋型
        String deadthree1a = "22200";// 死三棋型1
        String deadthree1b = "00222";
        String deadthree2a = "02022";// 死三棋型2
        String deadthree2b = "20220";
        String deadthree2c = "02202";
        String deadthree2d = "22020";
        String deadthree3a = "20022";// 死三棋型3
        String deadthree3b = "22002";
        String deadthree4 = "20202";// 死三棋型4
        String livetwo = "00022000";// 活二棋型
        String deadtwo1a = "22000";// 死二棋型1
        String deadtwo1b = "02200";
        String deadtwo1c = "00220";
        String deadtwo1d = "00022";
        String deadtwo2a = "00202";// 死二棋型2
        String deadtwo2b = "20200";
        String deadtwo2c = "02020";
        String deadtwo3a = "02002";// 死二棋型3
        String deadtwo3b = "20020";
        String deadone1 = "00002";// 死一棋型
        String deadone2 = "20000";
        library[0][0] = livefour;// 棋型放入数组中
        library[0][1] = 100000;// 此棋型产生的威胁值（或优势值）
        library[0][2] = 0;// 在此棋型0索引出下子可破解
        library[1][0] = deadfour1a;
        library[1][1] = 2501;
        library[1][2] = 0;
        library[2][0] = deadfour1b;
        library[2][1] = 2502;
        library[2][2] = 4;
        library[3][0] = deadfour2a;
        library[3][1] = 3301;
        library[3][2] = 3;
        library[4][0] = deadfour2b;
        library[4][1] = 3300;
        library[4][2] = 1;
        library[5][0] = deadfour3;
        library[5][1] = 2600;
        library[5][2] = 2;
        library[6][0] = livethree;
        library[6][1] = 3000;
        library[6][2] = 0;
        library[7][0] = deadthree1a;
        library[7][1] = 500;
        library[7][2] = 3;
        library[8][0] = deadthree1b;
        library[8][1] = 501;
        library[8][2] = 1;
        library[9][0] = deadthree2a;
        library[9][1] = 801;
        library[9][2] = 2;
        library[10][0] = deadthree2b;
        library[10][1] = 802;
        library[10][2] = 1;
        library[11][0] = deadthree2c;
        library[11][1] = 803;
        library[11][2] = 3;
        library[12][0] = deadthree2d;
        library[12][1] = 804;
        library[12][2] = 2;
        library[13][0] = deadthree3a;
        library[13][1] = 601;
        library[13][2] = 2;
        library[14][0] = deadthree3b;
        library[14][1] = 602;
        library[14][2] = 2;
        library[15][0] = deadthree4;
        library[15][1] = 551;
        library[15][2] = 1;
        library[16][0] = livetwo;
        library[16][1] = 651;
        library[16][2] = 2;
        library[17][0] = deadtwo1a;
        library[17][1] = 151;
        library[17][2] = 2;
        library[18][0] = deadtwo1b;
        library[18][1] = 152;
        library[18][2] = 3;
        library[19][0] = deadtwo1c;
        library[19][1] = 153;
        library[19][2] = 1;
        library[20][0] = deadtwo1d;
        library[20][1] = 154;
        library[20][2] = 2;
        library[21][0] = deadtwo2a;
        library[21][1] = 255;
        library[21][2] = 1;
        library[22][0] = deadtwo2b;
        library[22][1] = 254;
        library[22][2] = 3;
        library[23][0] = deadtwo2c;
        library[23][1] = 253;
        library[23][2] = 2;
        library[24][0] = deadtwo3a;
        library[24][1] = 201;
        library[24][2] = 2;
        library[25][0] = deadtwo3b;
        library[25][1] = 200;
        library[25][2] = 2;
        library[26][0] = deadone1;
        library[26][1] = 101;
        library[26][2] = 3;
        library[27][0] = deadone2;
        library[27][1] = 100;
        library[27][2] = 1;

        /*----- 将棋型库数组按照棋型估值（威胁值或优势值）升序排列，确保最后判断最有威胁的棋型---- */
        int index;// 快速排序索引标记
        for (int i = 1; i < library.length; i++) {// 遍历数组行
            index = 0;// 索引标记归0
            for (int j = 1; j <= library.length - i; j++) {// 遍历数组列
                int valueA = (int) library[j][1];// 记录当前行的估值
                int valueB = (int) library[index][1];// 记录索引行的估值
                if (valueA > valueB) {// 如果当前行比索引行评分高
                    index = j;// 将当前航记录为索引行
                }
            }
            // 将评分最大的行放到数组的最末尾
            // 交换估值
            Object value = library[library.length - i][1]; // 把第一个元素值保存到临时变量中
            library[library.length - i][1] = library[index][1]; // 把第二个元素值保存到第一个元素单元中
            library[index][1] = value; // 把临时变量也就是第一个元素原值保存到第二个元素中
            // 交换棋型
            Object key = library[library.length - i][0];
            library[library.length - i][0] = library[index][0];
            library[index][0] = key;
            // 交换破解位置
            Object step = library[library.length - i][2];
            library[library.length - i][2] = library[index][2];
            library[index][2] = step;
        }
        /*------------------------快速排序完毕-----------------*/
        return library;

    }



    /**
     *
     *     以下是判断AI的白棋棋型评分，需要和黑棋的小一分
     *
     *
     * */
    private static int[] catchChessModelb(int x, int y) {

        // 索引0：记录此位置的棋子可产生的最大威胁值或优势值
        // 索引1：对应下棋横坐标
        // 索引2：对应下棋横坐标
        int position[] = new int[3];

        // 创建以被捕捉棋子为中心的四个方向形成的棋型
        // 以参数点为中心点，保存四个方向的棋型，方向分别为 — | \ /
        int model[][] = new int[4][11];
        for (int tmp[] : model) {// 遍历数组
            Arrays.fill(tmp, 8);// 将数组填充为边界常量
        }
        // 把参数点放入每行的中心部位
        model[0][5] = model[1][5] = model[2][5] = model[3][5] = lst[x][y];
        // 以该棋子为中心，向两边走5步
        for (int i = 1; i <= 5; i++) {
            // 水平方向棋型
            if (x - i >= 0) {// 如果没有走出边界
                model[0][5 - i] = lst[x - i][y];// 将左侧棋子记录到水平棋型当中
            }
            if (x + i <= 14) {// 如果没有走出边界
                model[0][5 + i] = lst[x + i][y];// 将右侧棋子记录到水平棋型当中
            }
        }
        for (int i = 0; i < 5; i++) {
            // 垂直方向棋型
            if (y - i >= 0) {// 如果没有走出边界
                model[1][5 - i] = lst[x][y - i];// 将上方棋子记录到垂直棋型当中
            }
            if (y + i <= 14) {// 如果没有走出边界
                model[1][5 + i] = lst[x][y + i];// 将下方棋子记录到垂直棋型当中
            }
        }
        for (int i = 0; i < 5; i++) {
            // 反斜杠方向棋型
            if (x - i >= 0 && y + i <= 14) {// 如果没有走出边界
                model[2][5 - i] = lst[x - i][y + i];// 将左下方棋子记录到反斜棋型当中
            }
            if (x + i <= 14 && y - i >= 0) {// 如果没有走出边界
                model[2][5 + i] = lst[x + i][y - i];// 将右上方棋子记录到反斜棋型当中
            }
        }
        for (int i = 0; i < 5; i++) {
            // 正斜杠方向棋型
            if (x - i >= 0 && y - i >= 0) {// 如果没有走出边界
                model[3][5 - i] = lst[x - i][y - i];// 将左上方棋子记录到正斜棋型当中
            }
            if (x + i <= 14 && y + i <= 14) {// 如果没有走出边界
                model[3][5 + i] = lst[x + i][y + i];// 将右下方棋子记录到正斜棋型当中
            }
        }
        int score = 0;// 记录最大评分（威胁值）
        int direction = -1;// 记录最大评分的方向（model数组一维下标）
        int index = 0;// 记录坐标偏移量(judgeModle()方法给予的破解位置)
        for (int i = 0; i < model.length; i++) {// 遍历棋型数组
            int getResult[] = judgeModleb(model[i]);// 针对此方向棋型，给予破解方案
            if (score < getResult[1]) {// 如果出现比当前最大威胁值还要大的威胁
                score = getResult[1];// 更新最大分（威胁值）
                // 被捕捉的棋子在模型中的索引为5，getResult[0]为破解方案中的下棋索引位置
                // getResult[0] - 5 = 破解位置距离被捕捉的棋子的索引位置
                index = getResult[0] - 5;//
                direction = i;// 记录此棋型的方向
            }
        }
        switch (direction) {// 判断最大威胁值所在的方向
            case 0:// 如果是水平方向
                x += index;// 下棋的位置是原位置向右（或向左）偏移index的值
                break;
            case 1:// 如果是垂直方向
                y += index;// 下棋的位置是原位置向下（或向上）偏移index的值
                break;
            case 2:// 如果是反斜方向
                x += index;// 下棋的位置是原位置向右（或向左）偏移index的值
                y -= index;// 下棋的位置是原位置向上（或向下）偏移index的值
                break;
            case 3:// 如果是正斜方向
                x += index;// 下棋的位置是原位置向右（或向左）偏移index的值
                y += index;// 下棋的位置是原位置向下（或向上）偏移index的值
                break;
        }
        position[0] = score;// 记录此棋子的最大评分（威胁值）
        position[1] = x;// 记录对应下棋横坐标
        position[2] = y;// 记录对应下棋纵坐标

        return position;// 返回结果数组
    }

    public static int[] judgeModleb(int model[]) {
        int piont[] = new int[2];// 初始化返回结果数组
        int score = 0;// 记录最大评分
        StringBuffer sb = new StringBuffer();// 准备将棋型数组保存为字符串的StringBuffer
        for (int num : model) {// 遍历数组，将数组变成字符串
            if (num == 2) {// 如果是白zi
                num = 4;// 改为其他数字，以免负号会占字符
            }
            sb.append(num);// 字符串添加此数字
        }

        Object library[][] = getModelLibraryb();// 获取棋型库中所有棋型及其解决方案
        for (int i = 0; i < library.length; i++) {// 遍历棋型库
            String chessModel = (String) library[i][0];// 获取库中棋型
            int modelIndex = -1;// 临时变量，用于保存某棋型在字符串中出现的索引位置
            if ((modelIndex = sb.indexOf(chessModel)) != -1) {// 如果存在此棋型，则将棋型出现的位置付给modelIndex
                int scoreInLib = (int) library[i][1];// 获取棋型评分
                int stepIndex = (int) library[i][2];// 获取对应的下棋位置
                if (score < scoreInLib) {// 如果出现更高的评分
                    score = scoreInLib;// 更新最大分
                    // 记录应该(在这一行中)下棋的实际索引位置。
                    // 棋型在字符串中的索引位置 + 棋型给出的解决位置 = 字符串中的解决位置
                    piont[0] = modelIndex + stepIndex;
                    piont[1] = score;// 记录最大分数
                }
            }
        }
        return piont;// 返回结果数组
    }

    private static Object[][] getModelLibraryb() {
        // 棋型库数组，第一列保存棋型字符串，第二列保存棋型估值,第三列保存针对此棋型的下法
        Object[][] library = new Object[28][3];
        // 一行可能出现的棋型，1表示棋子，0表示空位置

        String livefour = "011110";// 活四棋型

        String deadfour1a = "01111";// 死四棋型1
        String deadfour1b = "11110";
        String deadfour2a = "11101";// 死四棋型2
        String deadfour2b = "10111";

        String deadfour3 = "11011";// 死四棋型3

        String livethree = "01110";// 活三棋型
        String deadthree1a = "11100";// 死三棋型1
        String deadthree1b = "00111";
        String deadthree2a = "01011";// 死三棋型2
        String deadthree2b = "10110";
        String deadthree2c = "01101";
        String deadthree2d = "11010";
        String deadthree3a = "10011";// 死三棋型3
        String deadthree3b = "11001";
        String deadthree4 = "10101";// 死三棋型4

        String livetwo = "00011000";// 活二棋型

        String deadtwo1a = "11000";// 死二棋型1
        String deadtwo1b = "01100";
        String deadtwo1c = "00110";
        String deadtwo1d = "00011";
        String deadtwo2a = "00101";// 死二棋型2
        String deadtwo2b = "10100";
        String deadtwo2c = "01010";
        String deadtwo3a = "01001";// 死二棋型3
        String deadtwo3b = "10010";
        String deadone1 = "00001";// 死一棋型
        String deadone2 = "10000";
        library[0][0] = livefour;// 棋型放入数组中
        library[0][1] = 100001;// 此棋型产生的威胁值（或优势值）
        library[0][2] = 0;// 在此棋型0索引出下子可破解
        library[1][0] = deadfour1a;
        library[1][1] = 3004;
        library[1][2] = 0;
        library[2][0] = deadfour1b;
        library[2][1] = 3003;
        library[2][2] = 4;
        library[3][0] = deadfour2a;
        library[3][1] = 3302;
        library[3][2] = 3;
        library[4][0] = deadfour2b;
        library[4][1] = 3301;
        library[4][2] = 1;
        library[5][0] = deadfour3;
        library[5][1] = 3300;
        library[5][2] = 2;
        library[6][0] = livethree;
        library[6][1] = 3001;
        library[6][2] = 0;
        library[7][0] = deadthree1a;
        library[7][1] = 500;
        library[7][2] = 3;
        library[8][0] = deadthree1b;
        library[8][1] = 501;
        library[8][2] = 1;
        library[9][0] = deadthree2a;
        library[9][1] = 801;
        library[9][2] = 2;
        library[10][0] = deadthree2b;
        library[10][1] = 802;
        library[10][2] = 1;
        library[11][0] = deadthree2c;
        library[11][1] = 803;
        library[11][2] = 3;
        library[12][0] = deadthree2d;
        library[12][1] = 804;
        library[12][2] = 2;
        library[13][0] = deadthree3a;
        library[13][1] = 601;
        library[13][2] = 2;
        library[14][0] = deadthree3b;
        library[14][1] = 602;
        library[14][2] = 2;
        library[15][0] = deadthree4;
        library[15][1] = 551;
        library[15][2] = 1;
        library[16][0] = livetwo;
        library[16][1] = 651;
        library[16][2] = 2;
        library[17][0] = deadtwo1a;
        library[17][1] = 151;
        library[17][2] = 2;
        library[18][0] = deadtwo1b;
        library[18][1] = 152;
        library[18][2] = 3;
        library[19][0] = deadtwo1c;
        library[19][1] = 153;
        library[19][2] = 1;
        library[20][0] = deadtwo1d;
        library[20][1] = 600;
        library[20][2] = 2;
        library[21][0] = deadtwo2a;
        library[21][1] = 255;
        library[21][2] = 1;
        library[22][0] = deadtwo2b;
        library[22][1] = 254;
        library[22][2] = 3;
        library[23][0] = deadtwo2c;
        library[23][1] = 253;
        library[23][2] = 2;
        library[24][0] = deadtwo3a;
        library[24][1] = 201;
        library[24][2] = 2;
        library[25][0] = deadtwo3b;
        library[25][1] = 200;
        library[25][2] = 2;
        library[26][0] = deadone1;
        library[26][1] = 501;
        library[26][2] = 3;
        library[27][0] = deadone2;
        library[27][1] = 100;
        library[27][2] = 1;

        /*----- 将棋型库数组按照棋型估值（威胁值或优势值）升序排列，确保最后判断最有威胁的棋型---- */
        int index;// 快速排序索引标记
        for (int i = 1; i < library.length; i++) {// 遍历数组行
            index = 0;// 索引标记归0
            for (int j = 1; j <= library.length - i; j++) {// 遍历数组列
                int valueA = (int) library[j][1];// 记录当前行的估值
                int valueB = (int) library[index][1];// 记录索引行的估值
                if (valueA > valueB) {// 如果当前行比索引行评分高
                    index = j;// 将当前航记录为索引行
                }
            }
            // 将评分最大的行放到数组的最末尾
            // 交换估值
            Object value = library[library.length - i][1]; // 把第一个元素值保存到临时变量中
            library[library.length - i][1] = library[index][1]; // 把第二个元素值保存到第一个元素单元中
            library[index][1] = value; // 把临时变量也就是第一个元素原值保存到第二个元素中
            // 交换棋型
            Object key = library[library.length - i][0];
            library[library.length - i][0] = library[index][0];
            library[index][0] = key;
            // 交换破解位置
            Object step = library[library.length - i][2];
            library[library.length - i][2] = library[index][2];
            library[index][2] = step;
        }
        /*------------------------快速排序完毕-----------------*/
        return library;

    }





}
